home *** CD-ROM | disk | FTP | other *** search
- /* * This file forms part of CorVu dbCGI * * CorVu dbCGI is Copyright (C) 1995 CorVu Pty Ltd. * Written by Troy Rollo * * CorVu dbCGI is free software. It may be modified and redistributed under * the terms of the CorVu General Public License, either version 1, or, at * your option, any later version. Ensure that you read this license before * modifying or redistributing the software. * * THIS PROGRAM IS PROVIDED "AS IS" WITH NO WORRANTY OF ANY KIND. YOU USE * THIS PROGRAM ENTIRELY AT YOUR OWN RISK. NEITHER CORVU, NOR ANY OTHER * PARTY MAY BE HELD RESPONSIBLE FOR ANY DAMAGES ARISING FROM YOUR USE OR * MISUSE OF THIS PROGRAM. */#include "dbcgi.h"#include <sql.h>#include <sqlext.h>typedef struct __dbw_conninfo{ HDBC hdbc; HSTMT hstmt;} dbw_conninfo;static dbw_typemap atm[] ={ { SQL_CHAR, 0, SQL_C_CHAR, DBWT_Char }, { SQL_VARCHAR, 0, SQL_C_CHAR, DBWT_Char }, { SQL_LONGVARCHAR, 0, SQL_C_CHAR, DBWT_Char }, { SQL_BINARY, 0, SQL_C_CHAR, DBWT_Raw }, { SQL_VARBINARY, 0, SQL_C_CHAR, DBWT_Raw }, { SQL_LONGVARBINARY, 0, SQL_C_CHAR, DBWT_Raw }, { SQL_BIT, 0, SQL_C_LONG, DBWT_Int }, { SQL_DECIMAL, 0, SQL_C_LONG, DBWT_Dec }, { SQL_NUMERIC, 0, SQL_C_LONG, DBWT_Dec }, { SQL_TINYINT, 0, SQL_C_LONG, DBWT_Int }, { SQL_SMALLINT, 0, SQL_C_LONG, DBWT_Int }, { SQL_INTEGER, 0, SQL_C_LONG, DBWT_Int }, { SQL_BIGINT, 0, SQL_C_DOUBLE, DBWT_Float }, { SQL_REAL, 0, SQL_C_DOUBLE, DBWT_Float }, { SQL_FLOAT, 0, SQL_C_DOUBLE, DBWT_Float }, { SQL_DOUBLE, 0, SQL_C_DOUBLE, DBWT_Float }, { SQL_TIME, 9, SQL_C_CHAR, DBWT_Char }, { SQL_DATE, 11, SQL_C_CHAR, DBWT_Char }, { SQL_TIMESTAMP, 27, SQL_C_CHAR, DBWT_Char }};static HENV henv = 0;static voidSendErrorMessage(dbw_conninfo *pinfo, int iCode, char *pchSQL){ static char achError[SQL_MAX_MESSAGE_LENGTH]; SDWORD sdword; char sqlstate[6]; SWORD sword; switch(iCode) { case 2: while (SQLError(henv, pinfo->hdbc, pinfo->hstmt, sqlstate, &sdword, achError, SQL_MAX_MESSAGE_LENGTH - 1, &sword) == SQL_SUCCESS) FormatErrors(sdword, achError, pchSQL); case 1: while (SQLError(henv, pinfo->hdbc, SQL_NULL_HSTMT, sqlstate, &sdword, achError, SQL_MAX_MESSAGE_LENGTH - 1, &sword) == SQL_SUCCESS) FormatErrors(sdword, achError, pchSQL); case 0: while (SQLError(henv, SQL_NULL_HDBC, SQL_NULL_HSTMT, sqlstate, &sdword, achError, SQL_MAX_MESSAGE_LENGTH - 1, &sword) == SQL_SUCCESS) FormatErrors(sdword, achError, pchSQL); }}static void RunQuery(dbw_value *pval, int iGetResults){ int iColumn; SWORD nColumns; char *pchCommand = GetValue(pval, "Query"); SWORD iStrLen; SWORD iNullable; UDWORD iColumnWidth; SWORD iColType; SWORD iColumnPrec; char achColumnName[256]; dbw_result *prslt; SDWORD *piIndicators; dbw_bindinfo *pbi; int iStatus; dbw_conninfo *pinfo = FindConnection(pval); if (!pinfo) return; if (SQLAllocStmt(pinfo->hdbc, &pinfo->hstmt) == SQL_ERROR) { SendErrorMessage(pinfo, 1, pchCommand); FreeString(pchCommand); return; } SQLSetScrollOptions(pinfo->hstmt, SQL_CONCUR_READ_ONLY, SQL_SCROLL_FORWARD_ONLY, 1); if (SQLPrepare(pinfo->hstmt, pchCommand, SQL_NTS) == SQL_ERROR) { SendErrorMessage(pinfo, 2, pchCommand); SQLFreeStmt(pinfo->hstmt, SQL_DROP); FreeString(pchCommand); return; } if (iGetResults && SQLExecute(pinfo->hstmt) == SQL_ERROR) { SendErrorMessage(pinfo, 2, pchCommand); SQLFreeStmt(pinfo->hstmt, SQL_DROP); FreeString(pchCommand); return; } if (!iGetResults) { FreeString(pchCommand); SQLFreeStmt(pinfo->hstmt, SQL_DROP); return; } if (SQLNumResultCols(pinfo->hstmt, &nColumns) == SQL_ERROR) { SendErrorMessage(pinfo, 2, pchCommand); FreeString(pchCommand); SQLFreeStmt(pinfo->hstmt, SQL_DROP); return; } prslt = new2(dbw_result, nColumns); piIndicators = new2(SDWORD, nColumns); for (iColumn = 0; iColumn < nColumns; iColumn++) { SQLDescribeCol(pinfo->hstmt, iColumn + 1, achColumnName, sizeof(achColumnName) - 1, &iStrLen, &iColType, &iColumnWidth, &iColumnPrec, &iNullable); achColumnName[iStrLen] = 0; pbi = FindColInfo(atm, rangeof(atm), &prslt[iColumn], achColumnName, iColType, iColumnWidth, -1); SQLBindCol(pinfo->hstmt, iColumn+1, pbi->iBindType, pbi->pchData, pbi->iWidth, piIndicators + iColumn); } FormatHeadings(prslt, nColumns); while ((iStatus = SQLFetch(pinfo->hstmt)) != SQL_NO_DATA_FOUND) { if (iStatus == SQL_STILL_EXECUTING) { FlushMessages(); continue; } if (iStatus == SQL_ERROR) { SendErrorMessage(pinfo, 2, pchCommand); break; } for (iColumn = 0; iColumn < nColumns; iColumn++) prslt[iColumn].iIsNull = (piIndicators[iColumn] == SQL_NULL_DATA); FormatOutput(prslt, nColumns); } SQLFreeStmt(pinfo->hstmt, SQL_DROP); SQLTransact(henv, pinfo->hdbc, SQL_COMMIT); free(piIndicators); free(prslt); FreeString(pchCommand);}voidDBQuery(dbw_value *pval){ RunQuery(pval, 1);}voidDBExecute(dbw_value *pval){ RunQuery(pval, 0);}static char hda[256];voidDBDisconnect(dbw_value *pval){ dbw_conninfo *pinfo = FindConnection(pval); if (!pinfo) return; if (SQLDisconnect(pinfo->hdbc) == SQL_ERROR) SendErrorMessage(pinfo, 1, "Disconnect"); if (SQLFreeConnect(pinfo->hdbc) == SQL_ERROR) SendErrorMessage(pinfo, 1, "Free Connection"); DropConnection(pval);}voidDBInit(dbw_value *pval){ if (SQLAllocEnv(&henv) == SQL_ERROR) FormatErrors(0, "Out of memory", "Initialising");}voidDBUnInit(dbw_value *pval){ if (SQLFreeEnv(henv) == SQL_ERROR) SendErrorMessage(0, 0, "Free Environment");}voidDBConnect(dbw_value *pval){ char *pchUser = GetValue(pval, "USER"); char *pchPass = GetValue(pval, "PASS"); char *pchDataSource = GetValue(pval, "DATASOURCE"); char *pchConnString = GetValue(pval, "CONN_STR"); char *pchAutoCommit = GetValue(pval, "AUTOCOMMIT"); char *pchReadOnly = GetValue(pval, "READONLY"); BOOL bConnected = FALSE; dbw_conninfo *pinfo = new(dbw_conninfo); if (!AddConnection(pval, pinfo)) { free(pinfo); return; } pinfo->hdbc = 0; pinfo->hstmt = 0; if (SQLAllocConnect(henv, &pinfo->hdbc) == SQL_ERROR) { SendErrorMessage(pinfo, 0, "Connecting"); SQLFreeEnv(henv); DropConnection(pval); return; } if (pchConnString) { if (SQLDriverConnect( pinfo->hdbc, GetFocus(), pchConnString, SQL_NTS, 0, SQL_NULL_DATA, 0, SQL_DRIVER_COMPLETE) == SQL_ERROR) { SendErrorMessage(pinfo, 1, "Connecting"); SQLFreeConnect(pinfo->hdbc); DropConnection(pval); } else { bConnected = TRUE; } } else { if (SQLConnect( pinfo->hdbc, pchDataSource, SQL_NTS, pchUser, SQL_NTS, pchPass, SQL_NTS) == SQL_ERROR) { SendErrorMessage(pinfo, 1, "Connecting"); SQLFreeConnect(pinfo->hdbc); DropConnection(pval); } else { bConnected = TRUE; } } if (bConnected) { if (pchReadOnly && *pchReadOnly == '1') SQLSetConnectOption(pinfo->hdbc, SQL_ACCESS_MODE, SQL_MODE_READ_ONLY); if (pchAutoCommit && *pchAutoCommit == '1') SQLSetConnectOption(pinfo->hdbc, SQL_AUTOCOMMIT, 1); } FreeString(pchAutoCommit); FreeString(pchReadOnly); FreeString(pchConnString); FreeString(pchUser); FreeString(pchPass); FreeString(pchDataSource);}